<?php

namespace app\crontab\controller;

use app\common\logic\Queue;
use think\Cache;
/**
 * ============================================================================
 * DSMall多用户商城
 * ============================================================================
 * 版权所有 2014-2028 长沙德尚网络科技有限公司，并保留所有权利。
 * 网站地址: http://www.csdeshang.com
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用 .
 * 不允许对程序代码以任何形式任何目的的再发布。
 * ============================================================================
 * 定时器
 */
class  Minutes extends BaseCron {

    /**
     * 默认方法
     */
    public function index() {
        $this->_o2o_distributor_order_auto_reject();
        $this->_o2o_distributor_order_auto_receipt();
        $this->_o2o_distributor_order_auto_deliver();
        $this->_o2o_distributor_notice();
        $this->_cron_queue();
        $this->_cron_common();
        $this->_cron_mail_send();
        $this->_cron_bonus();
    }

    /*
     * 给店铺自动拒单
     */

    private function _o2o_distributor_order_auto_reject() {
        //设置了自动拒绝订单的店铺
        $order_ids = db('order')->alias('order_alias')->join('__STORE__ store', 'order_alias.store_id=store.store_id')->whereRaw('order_alias.payment_time<(' . TIMESTAMP . '-store.store_o2o_reject_time*60)')->where(['order_alias.order_state' => ORDER_STATE_PAY, 'order_alias.lock_state' => 0, 'order_alias.refund_state' => 0, 'store.store_o2o_reject_time' => ['>', 0]])->limit(100)->column('order_alias.order_id');
        $refundreturn_model = model('refundreturn');
        $order_model = model('order');
        foreach ($order_ids as $order_id) {
            $refundreturn_model->startTrans();
            try {
                $order_info = db('order')->field('order_id,order_sn,store_id,store_name,buyer_id,buyer_name,refund_amount,order_amount')->where(['order_id' => $order_id, 'order_state' => ORDER_STATE_PAY, 'lock_state' => 0, 'refund_state' => 0])->lock()->find();
                if ($order_info) {
                    $book_amount = $order_info['refund_amount']; //退款金额
                    $allow_refund_amount = ds_price_format($order_info['order_amount'] - $book_amount); //可退款金额

                    $refund_array = array();
                    $refund_array['refund_type'] = '1'; //类型:1为退款,2为退货
                    $refund_array['seller_state'] = '2'; //状态:1为待审核,2为同意,3为不同意
                    $refund_array['order_lock'] = '2'; //锁定类型:1为不用锁定,2为需要锁定
                    $refund_array['goods_id'] = '0';
                    $refund_array['order_goods_id'] = '0';
                    $refund_array['reason_id'] = '0';
                    $refund_array['reason_info'] = '店铺拒绝订单，订单退款';
                    $refund_array['goods_name'] = '订单商品全部退款';
                    $refund_array['refund_amount'] = ds_price_format($allow_refund_amount);
                    $refund_array['buyer_message'] = '';
                    $refund_array['add_time'] = time();
                    $refund_array['seller_time'] = time();
                    $refund_array['refund_state'] = '2';
                    $refund_array['seller_message'] = '超过拒接时限，自动拒绝订单';


                    $state = $refundreturn_model->addRefundreturn($refund_array, $order_info);
                    if ($state) {
                        $refundreturn_model->editOrderLock($order_id);
                    } else {
                        exception('退款申请保存失败');
                    }
                }
                $refundreturn_model->commit();
            } catch (\Exception $e) {
                $this->log('自动拒单失败，订单id：' . $order_id . '：' . $e->getMessage());
                $refundreturn_model->rollback();
            }
        }
    }

    /*
     * 给店铺自动接单
     */

    private function _o2o_distributor_order_auto_receipt() {
        //店铺状态为开启状态，接单状态为开启状态，自动接单状态为开启状态，在营业时间内，不超过接单上限的店铺
        //$subQuery=db('store')->alias('store')->join('__ORDER__ order_alias','order_alias.store_id=store.store_id','LEFT')->field('store.store_id')->where(array('store.store_state'=>1,'store.store_o2o_receipt'=>1,'store.store_o2o_auto_receipt'=>1,'store.store_o2o_open_start'=>array('<',floor(TIMESTAMP-strtotime(date('Y-m-d 0:0:0'))/60)),'store.store_o2o_open_end'=>array('>',floor(TIMESTAMP-strtotime(date('Y-m-d 0:0:0'))/60))))->group('store.store_id')->having('CASE WHEN store.store_o2o_receipt_limit>0 THEN COUNT(order_alias.order_state IN (' . ORDER_STATE_RECEIPT . ') OR NULL) < store.store_o2o_receipt_limit ELSE 1=1 END')->buildSql();
        //如果这些店铺存在待接单的订单
        $order_list = db('order')->field('store_id,store_name,order_id,order_sn,buyer_id,buyer_name,o2o_order_distributor_type')->where(array('order_state' => ORDER_STATE_PAY, 'refund_state' => 0, 'lock_state' => 0,))->order('o2o_order_receipt_priority asc')->limit(100)->select();
        $store_list = array();
        $store_model = model('store');
        $order_model = model('order');
        $o2o_distributor_notice_model = model('o2o_distributor_notice');
        foreach ($order_list as $order_info) {
            $order_model->startTrans();
            try {
                $update_order = array();
                if (!isset($store_list[$order_info['store_id']])) {
                    $store_list[$order_info['store_id']] = $store_model->field('store_id,store_name,store_state,store_o2o_receipt_limit,store_o2o_receipt,store_o2o_auto_receipt,store_o2o_auto_deliver,store_o2o_open_start,store_o2o_open_end,region_id')->where(array('store_id' => $order_info['store_id']))->find();
                }
                if ($store_list[$order_info['store_id']]) {
                    $ret = $store_model->getO2oState($store_list[$order_info['store_id']]);
                    if ($ret['code']) {//如果店铺在营业时间内没有关闭接单
                        $order_receipt_data = $order_model->autoOrderReceipt($store_list[$order_info['store_id']], $order_info);
                        if ($order_receipt_data) {
                            $update_order = array_merge($update_order, $order_receipt_data);
                            $order_deliver_data = $order_model->autoOrderDeliver($store_list[$order_info['store_id']], $order_info);
                            if ($order_deliver_data) {
                                $update_order = array_merge($update_order, $order_deliver_data);
                                $update_order['o2o_order_source'] = 1;
                            }
                        } else {
                            db('order')->where(array('order_id' => $order_info['order_id']))->setInc('o2o_order_receipt_priority');
                        }
                        if ($update_order) {
                            $update = $order_model->editOrder($update_order, array(
                                'order_id' => $order_info['order_id'], 'order_state' => ORDER_STATE_PAY, 'refund_state' => 0, 'lock_state' => 0,
                            ));
                            if (!$update) {
                                exception('修改订单状态失败');
                            }
                            if (in_array($update_order['order_state'], [ORDER_STATE_RECEIPT, ORDER_STATE_DELIVER])) {
                                $data = array();
                                $data['order_id'] = $order_info['order_id'];
                                $data['log_role'] = 'system';
                                $data['log_user'] = '';
                                $data['log_msg'] = '自动为店铺接单';
                                $data['log_orderstate'] = ORDER_STATE_RECEIPT;
                                $order_model->addOrderlog($data);
                                if (in_array($update_order['order_state'], [ORDER_STATE_DELIVER])) {
                                    $data = array();
                                    $data['order_id'] = $order_info['order_id'];
                                    $data['log_role'] = 'system';
                                    $data['log_user'] = '';
                                    $data['log_msg'] = '自动派单给配送员' . $update_order['o2o_distributor_name'];
                                    $data['log_orderstate'] = ORDER_STATE_DELIVER;
                                    $order_model->addOrderlog($data);


                                    //生成订单通知
                                    $o2o_distributor_notice_model->addO2oDistributorNotice(array(
                                        'o2o_distributor_id' => $update_order['o2o_distributor_id'],
                                        'o2o_distributor_name' => $update_order['o2o_distributor_name'],
                                        'o2o_distributor_notice_type' => 1,
                                        'order_id' => $order_info['order_id'],
                                        'o2o_distributor_notice_title' => lang('ds_o2o_distributor_notice_type_text')[1],
                                        'o2o_distributor_notice_content' => sprintf(lang('ds_o2o_distributor_notice_system'), $order_info['order_sn']),
                                        'o2o_distributor_notice_add_time' => TIMESTAMP,
                                    ));
                                }
                            }
                        }
                    } else {
                        db('order')->where(array('order_id' => $order_info['order_id']))->setInc('o2o_order_receipt_priority');
                    }
                } else {
                    db('order')->where(array('order_id' => $order_info['order_id']))->setInc('o2o_order_receipt_priority');
                }
                $order_model->commit();
            } catch (\Exception $e) {
                $this->log('自动接单失败，订单id：' . $order_info['order_id'] . '：' . $e->getMessage());
                $order_model->rollback();
            }
        }
    }

    /*
     * 给配送员自动派单
     */

    private function _o2o_distributor_order_auto_deliver() {
        $order_list = db('order')->field('store_id,store_name,order_id,order_sn,buyer_id,buyer_name,o2o_order_distributor_type')->where(array('order_state' => ORDER_STATE_RECEIPT, 'refund_state' => 0, 'lock_state' => 0,))->order('o2o_order_deliver_priority asc')->limit(100)->select();
        $store_list = array();
        $store_model = model('store');
        $order_model = model('order');
        $o2o_distributor_notice_model = model('o2o_distributor_notice');
        foreach ($order_list as $order_info) {
            $order_model->startTrans();
            try {

                if (!isset($store_list[$order_info['store_id']])) {
                    $store_list[$order_info['store_id']] = $store_model->field('store_id,store_name,store_state,store_o2o_receipt_limit,store_o2o_receipt,store_o2o_auto_receipt,store_o2o_auto_deliver,store_o2o_open_start,store_o2o_open_end,region_id')->where(array('store_id' => $order_info['store_id']))->find();
                }
                if ($store_list[$order_info['store_id']]) {
                    $update_order = $order_model->autoOrderDeliver($store_list[$order_info['store_id']], $order_info);
                    if ($update_order) {
                        $update_order['o2o_order_source'] = 1;
                        $update = $order_model->editOrder($update_order, array(
                            'order_id' => $order_info['order_id'], 'order_state' => ORDER_STATE_RECEIPT, 'refund_state' => 0, 'lock_state' => 0,
                        ));
                        if (!$update) {
                            exception('修改订单状态失败');
                        }
                        $data = array();
                        $data['order_id'] = $order_info['order_id'];
                        $data['log_role'] = 'system';
                        $data['log_user'] = '';
                        $data['log_msg'] = '自动派单给配送员' . $update_order['o2o_distributor_name'];
                        $data['log_orderstate'] = ORDER_STATE_DELIVER;
                        $order_model->addOrderlog($data);


                        //生成订单通知
                        $o2o_distributor_notice_model->addO2oDistributorNotice(array(
                            'o2o_distributor_id' => $update_order['o2o_distributor_id'],
                            'o2o_distributor_name' => $update_order['o2o_distributor_name'],
                            'o2o_distributor_notice_type' => 1,
                            'order_id' => $order_info['order_id'],
                            'o2o_distributor_notice_title' => lang('ds_o2o_distributor_notice_type_text')[1],
                            'o2o_distributor_notice_content' => sprintf(lang('ds_o2o_distributor_notice_system'), $order_info['order_sn']),
                            'o2o_distributor_notice_add_time' => TIMESTAMP,
                        ));
                    } else {
                        db('order')->where(array('order_id' => $order_info['order_id']))->setInc('o2o_order_deliver_priority');
                    }
                } else {
                    db('order')->where(array('order_id' => $order_info['order_id']))->setInc('o2o_order_deliver_priority');
                }
                $order_model->commit();
            } catch (\Exception $e) {
                $this->log('自动派单失败，订单id：' . $order_info['order_id'] . '：' . $e->getMessage());
                $order_model->rollback();
            }
        }
    }

    /*
     * 给配送员发送接单消息
     */

    private function _o2o_distributor_notice() {
        $order_ids = db('o2o_distributor_notice')->where(array('o2o_distributor_notice_read' => 0, 'o2o_distributor_notice_type' => 1,))->limit(100)->order('o2o_distributor_notice_id desc')->column('order_id');
        if ($order_ids) {
            $order_list = model('order')->getOrderList(array('order_id' => array('in', $order_ids), 'order_state' => array('in', array(ORDER_STATE_DELIVER))));

            $store_list = array();
            $store_model = model('store');
            $order_model = model('order');
            foreach ($order_list as $key => $val) {
                if (!isset($store_list[$val['store_id']])) {
                    $store_list[$val['store_id']] = $store_model->getStoreInfoByID($val['store_id']);
                }
                $order_list[$key] = $order_model->formatO2oOrder($store_list[$val['store_id']], $val);
            }
            o2o_send_order($order_list);
        }
    }

    /**
     * 邮件信息发送队列的处理
     */
    private function _cron_queue() {
        //获取当前存储的数量
        $QueueClientNum = Cache::get('QueueClientNum');
        $QueueLogic = new Queue();
        for ($i = 1; $i <= $QueueClientNum; $i++) {
            $info = Cache::pull('QueueClient_' . $i); #获取缓存
            if (empty($info)) {
                continue;
            }
            $info = unserialize($info);
            $key = key($info);
            $value = current($info);
            $QueueLogic->$key($value);
        }
        Cache::set('QueueClientNum', NULL);
    }
    /**
     * 处理过期红包
     */
    private function _cron_bonus() {
        $condition = array();
        $condition['bonus_endtime'] = array('lt', TIMESTAMP);
        $condition['bonus_state'] = 1;
        $data = array(
            'bonus_state' => 2,
        );
        model('bonus')->editBonus($condition, $data);
    }
    /**
     * 发送邮件消息
     */
    private function _cron_mail_send() {
        //每次发送数量
        $_num = 50;
        $storemsgcron_model = model('mailcron');
        $cron_array = $storemsgcron_model->getMailCronList(array(), $_num);
        if (!empty($cron_array)) {
            $email = new \sendmsg\Email();
            $mail_array = array();
            foreach ($cron_array as $val) {
                $return = $email->send_sys_email($val['mailcron_address'], $val['mailcron_subject'], $val['mailcron_contnet']);
                if ($return) {
                    // 记录需要删除的id
                    $mail_array[] = $val['mailcron_id'];
                }
            }
            // 删除已发送的记录
            $storemsgcron_model->delMailCron(array('mailcron_id' => array('in', $mail_array)));
        }
    }

    /**
     * 执行通用任务
     */
    private function _cron_common() {

        //查找待执行任务
        $cron_model = model('cron');
        $cron = $cron_model->getCronList(array('exetime' => array('elt', TIMESTAMP)));

        if (!is_array($cron))
            return;
        $cron_array = array();
        $cronid = array();
        foreach ($cron as $v) {
            $cron_array[$v['type']][$v['exeid']] = $v;
        }
        foreach ($cron_array as $k => $v) {
            // 如果方法不存是，直接删除id
            if (!method_exists($this, '_cron_' . $k)) {
                $tmp = current($v);
                $cronid[] = $tmp['id'];
                continue;
            }
            $result = call_user_func_array(array($this, '_cron_' . $k), array($v));
            if (is_array($result)) {
                $cronid = array_merge($cronid, $result);
            }
        }
        //删除执行完成的cron信息
        if (!empty($cronid) && is_array($cronid)) {
            $cron_model->delCron(array('id' => array('in', $cronid)));
        }
    }

    /**
     * 上架
     *
     * @param array $cron
     */
    private function _cron_1($cron = array()) {
        $condition = array('goods_commonid' => array('in', array_keys($cron)));
        $update = model('goods')->editProducesOnline($condition);
        if ($update) {
            //返回执行成功的cronid
            $cronid = array();
            foreach ($cron as $v) {
                $cronid[] = $v['id'];
            }
        } else {
            return false;
        }
        return $cronid;
    }

    /**
     * 根据商品id更新商品促销价格
     *
     * @param array $cron
     */
    private function _cron_2($cron = array()) {
        $condition = array('goods_id' => array('in', array_keys($cron)));
        $update = model('goods')->editGoodsPromotionPrice($condition);
        if ($update) {
            //返回执行成功的cronid
            $cronid = array();
            foreach ($cron as $v) {
                $cronid[] = $v['id'];
            }
        } else {
            return false;
        }
        return $cronid;
    }

    /**
     * 优惠套装过期
     *
     * @param array $cron
     */
    private function _cron_3($cron = array()) {
        //返回执行成功的cronid
        $cronid = array();
        return $cronid;
    }

    /**
     * 推荐展位过期
     *
     * @param array $cron
     */
    private function _cron_4($cron = array()) {
        //返回执行成功的cronid
        $cronid = array();
        return $cronid;
    }

    /**
     * 抢购开始更新商品促销价格
     *
     * @param array $cron
     */
    private function _cron_5($cron = array()) {
        //返回执行成功的cronid
        $cronid = array();
        return $cronid;
    }

    /**
     * 抢购过期
     *
     * @param array $cron
     */
    private function _cron_6($cron = array()) {
        $cronid = array();
        return $cronid;
    }

    /**
     * 限时折扣过期
     *
     * @param array $cron
     */
    private function _cron_7($cron = array()) {
        $condition = array('xianshi_id' => array('in', array_keys($cron)));
        //限时折扣过期
        $update = model('pxianshi')->editExpireXianshi($condition);
        if ($update) {
            //返回执行成功的cronid
            $cronid = array();
            foreach ($cron as $v) {
                $cronid[] = $v['id'];
            }
        } else {
            return false;
        }
        return $cronid;
    }

}

?>
